#pragma once

#ifndef VIDEO_HARDWARE_H
#define VIDEO_HARDWARE_H

#include "Types.h"

class VideoHardware
{
public:

	static const size_t video_width			= 224;
	static const size_t video_height		= 288;

	VideoHardware(const byte_t* const videoMemory, const byte_t* const spriteMemory, const byte_t* const spriteCoordsMemory);
	~VideoHardware();

	const byte_t* GetVideoMemory() const;

	void Update() const;

private:

	void DrawCharacters() const;
	void DrawCharacter(byte_t characterIndex, byte_t baseColor, byte_t* outPixels) const;
	void DrawCharacterHelper(byte_t * data, byte_t baseColor, byte_t* outPixels, size_t count, bool flipX = false, bool flipY = false) const;

	void DrawSprites() const;
	void DrawSprite(byte_t shape, byte_t mode, byte_t color, word_t xCoord, word_t yCoord) const;
	
	void ProcessRow(byte_t rowIndex, word_t start, word_t end) const;
	void ProcessColumns(word_t start, word_t end) const;

	VideoHardware(const VideoHardware&);
	VideoHardware& operator=(const VideoHardware&);

	const byte_t* m_videoMemory;
	const byte_t* m_colorMemory;
	const byte_t* m_spriteMemory;
	const byte_t* m_spriteCoordsMemory;

	byte_t* m_memory;

	mutable byte_t* m_outputImage;

	byte_t* m_colorsPalette;
	byte_t* m_charactersAndSpritesColors;
	byte_t* m_charactersDef;
	byte_t* m_spritesDef;
};

inline const byte_t* VideoHardware::GetVideoMemory() const
{
	return m_outputImage;
}

#endif
